/*
 * MIT License
 *
 * Copyright (c) 2020 wen.gu <454727014@qq.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

/***************************************************************************
 * Name: ngl_message.h
 *
 * Purpose: ngl message operation API define
 *
 * Developer:
 *   wen.gu , 2023-02-21
 *
 * TODO:
 *
 ***************************************************************************/
#ifndef __NGL_MESSAGE_H__
#define __NGL_MESSAGE_H__

#include <stdint.h>

#include "ngl/ngl_type.h"
#include "ngl/ngl_protocol.h"

#define NGL_MSG_SYNC_CODE 0xE5 
#define NGL_MSG_END_CODE 0xE6

#define NGL_ID_MAX_LEN 0xFF
#define NGL_HOST_NAME_MAX_LEN 0xFF
#define NGL_APP_ID_MAX_LEN 0xFF
#define NGL_CTX_ID_MAX_LEN 0xFF
#define NGL_MESSAGE_ID_LEN 4    /**< message id is a 32-bit unsigned int */
#define NGL_SESSION_ID_LEN 4    /**< session id is a 32-bit unsigned int */

#define NGL_EXT_HDR_MAX_LEN (NGL_HOST_NAME_MAX_LEN + NGL_APP_ID_MAX_LEN + NGL_CTX_ID_MAX_LEN + NGL_MESSAGE_ID_LEN + NGL_SESSION_ID_LEN)

#define NGL_BASE_HDR_LEN sizeof(ngl_base_header_t)
/***************************************************************************
 * Definitions of BaseHeader
 ***************************************************************************/
typedef struct _ngl_base_header_s {
    uint16_t htyp; /**< header type */
    uint8_t mcnt;  /**< message counter */
    uint8_t msin;  /**< message information */
    uint16_t mlen; /**< message length: sizeof(base header) + elen + sizeof (payload) */
    uint16_t elen; /**< extension header length */
    uint32_t ts_ns; /**< timestamp, ns field, range: 0 ~ 999999999 , bit 31:  0: start from 1970-01-01, 00:00:00 00000, 1: start from system boot */
    uint32_t ts_sec; /**< timestamp, second feild, range 0 ~ 4294967295(136 years) */
}ngl_base_header_t;

typedef struct _ngl_extension_header_s {
    uint16_t htyp; /**< header type */
    uint8_t host_name_len;
    uint8_t appid_len;
    uint8_t ctxid_len;
    uint32_t msessage_id;
    uint32_t session_id;
    uint8_t host_name[NGL_ID_MAX_LEN];
    uint8_t application_id[NGL_ID_MAX_LEN];
    uint8_t context_id[NGL_ID_MAX_LEN];
}ngl_extension_header_t;



typedef struct _ngl_message_s ngl_message_t;


#ifdef __cplusplus
extern "C" {
#endif



ngl_message_t* ngl_message_create(ngl_base_header_t* base_hdr);
ngl_error_t ngl_message_destroy(ngl_message_t* msg);


ngl_base_header_t* ngl_message_base_header(ngl_message_t* msg);

ngl_error_t ngl_message_set_extension_header(ngl_message_t* msg, const ngl_extension_header_t* ext_hdr);
ngl_error_t ngl_message_get_extension_header(ngl_message_t* msg, ngl_extension_header_t* ext_hdr);

uint8_t* ngl_message_get_extension_header_buffer(ngl_message_t* msg);
uint16_t ngl_message_get_extension_header_buffer_size(ngl_message_t* msg);


ngl_error_t ngl_message_set_payload(ngl_message_t* msg, const uint8_t* payload, uint16_t size);
uint8_t* ngl_message_payload(ngl_message_t* msg, uint16_t* size);
uint8_t* ngl_message_payload_buffer(ngl_message_t* msg);
uint16_t ngl_message_payload_buffer_size(ngl_message_t* msg);

ngl_error_t ngl_message_realloc_payload_buffer(ngl_message_t* msg, uint16_t new_size);

//get message serialized buffer(include sync code , end code )
uint8_t* ngl_message_serialized_buffer(ngl_message_t* msg, uint16_t* size);


uint16_t ngl_extension_header_get_length(const ngl_extension_header_t* ext_hdr);




#ifdef __cplusplus
}
#endif
#endif /** !__NGL_MESSAGE_H__ */
